package com.fling.objects;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.math.Vector2;
import com.fling.Locator;
import com.fling.entity.CollisionEntity;
import com.fling.hero.state.FallingState;
import com.fling.hero.state.HeroState;
import com.fling.observer.Event;
import com.fling.observer.Subject;

public class Hero extends CollisionEntity {

	private HeroState state;
	private boolean rightSide;
	private Subject subject;
	private Sprite flySprite, upSprite, climbSprite;
	public float X_JUMP_VEL = 288;
	public float Y_JUMP_VEL = 256;
	public float FALLING_VEL = -160;
	public static float SCALE = 0.66F;

	public Hero(Vector2 pos, Subject subject) {
		super(pos, TYPE.HERO, HERO_CLIMB_PATH, false, false, SCALE);
		rightSide = false;
		this.subject = subject;
		flySprite = new Sprite(new Texture(Gdx.files.internal(HERO_FLY_PATH)));
		upSprite = new Sprite(new Texture(Gdx.files.internal(HERO_UP_PATH)));
		climbSprite = new Sprite(new Texture(Gdx.files.internal(HERO_CLIMB_PATH)));
		state = new FallingState(this);
	}

	public void update(float delta) {
		if (exists) {
			super.update(delta);
			state.update(delta);
			if (position.y < -HERO_HEIGHT * Locator.getySpriteScale()) {
				die();
			}
		} else {
			subject.notify(this, Event.EVENT_RESTART);
			exists = true;
		}
	}

	public void die() {
		subject.notify(null, Event.EVENT_HERO_DIED);
		exists = false;
	}

	public void restart() {
		state = new FallingState(this);
		rightSide = false;
		flipX = false;
		flipY = false;
		exists = true;
	}

	public void jumpRight() {
		state.newAction(INPUT.JUMP_RIGHT);
	}

	public void jumpDown() {
		state.newAction(INPUT.JUMP_DOWN);
	}

	public void jumpUp() {
		state.newAction(INPUT.JUMP_UP);
	}

	public void jumpLeft() {
		state.newAction(INPUT.JUMP_LEFT);
	}

	public void climb() {
		state.newAction(INPUT.CLIMB);
	}

	public void fall() {
		state.newAction(INPUT.FALL);
	}

	@Override
	public void collide(CollisionEntity otherBody) {
		if (otherBody.getType().equals(TYPE.BLOCK)) {
			if (!Locator.isTutorialCompleted()) {
				subject.notify(this, Event.EVENT_TUTORIAL_DEATH);
			}
		} else if (otherBody.getType().equals(TYPE.COIN)) {
			if (Locator.difficulty == Locator.HARD) {
				subject.notify(this, Event.EVENT_COIN_GRABBED);
			}
		}
		state.collide(otherBody);

	}

	public void changeState(HeroState s) {
		state = s;
	}

	public boolean isRightSide() {
		return rightSide;
	}

	public void setRightSide(boolean rightSide) {
		this.rightSide = rightSide;
	}

	public Subject getSubject() {
		return subject;
	}

	public void setSubject(Subject subject) {
		this.subject = subject;
	}

	public Sprite getFlySprite() {
		return flySprite;
	}

	public void setFlySprite(Sprite flySprite) {
		this.flySprite = flySprite;
	}

	public Sprite getUpSprite() {
		return upSprite;
	}

	public void setUpSprite(Sprite upSprite) {
		this.upSprite = upSprite;
	}

	public Sprite getClimbSprite() {
		return climbSprite;
	}

	public void setClimbSprite(Sprite climbSprite) {
		this.climbSprite = climbSprite;
	}

}
